import asyncio

from PyQt5.QtCore import QObject, pyqtSignal
from bleak import BleakScanner, BleakClient

CHARACTERISTIC_UUID = "00002a37-0000-1000-8000-00805f9b34fb"
STANDARD_UUIDS = {
    "00001800-0000-1000-8000-00805f9b34fb": "Generic Access",
    "00001801-0000-1000-8000-00805f9b34fb": "Generic Attribute",
    "0000180d-0000-1000-8000-00805f9b34fb": "Heart Rate Service",
    "00002a37-0000-1000-8000-00805f9b34fb": "Heart Rate Measurement",
    "0000180f-0000-1000-8000-00805f9b34fb": "Battery Service",
    "00002a19-0000-1000-8000-00805f9b34fb": "Battery Level",
    "0000180a-0000-1000-8000-00805f9b34fb": "Device Information",
    "00002a29-0000-1000-8000-00805f9b34fb": "Manufacturer Name String",
    "00002a00-0000-1000-8000-00805f9b34fb": "Device Name",
    "00002a01-0000-1000-8000-00805f9b34fb": "Appearance",
    "00002a04-0000-1000-8000-00805f9b34fb": "Peripheral Preferred Conn. Params",
    "00002a24-0000-1000-8000-00805f9b34fb": "Model Number String",
    "00002a25-0000-1000-8000-00805f9b34fb": "Serial Number String",
    "00002a27-0000-1000-8000-00805f9b34fb": "Hardware Revision String",
    "00002a26-0000-1000-8000-00805f9b34fb": "Firmware Revision String",
    "00002a28-0000-1000-8000-00805f9b34fb": "Software Revision String",
    "00001809-0000-1000-8000-00805f9b34fb": "Health Thermometer",
    "00001810-0000-1000-8000-00805f9b34fb": "Blood Pressure",
    "00001808-0000-1000-8000-00805f9b34fb": "Glucose",
    "00001816-0000-1000-8000-00805f9b34fb": "Cycling Speed and Cadence",
    "00001814-0000-1000-8000-00805f9b34fb": "Running Speed and Cadence",
    "00001805-0000-1000-8000-00805f9b34fb": "Current Time Service",
    "00001525-1212-efde-1523-785feabcd123": "User Led Configuration"
}
# 线程通信桥
class BleWorker(QObject):
    result_ready = pyqtSignal(str)
    device_list_ready = pyqtSignal(list)

    def __init__(self, loop):
        super().__init__()
        self.loop = loop
        self.devices = []

    def start_scan(self):
        asyncio.run_coroutine_threadsafe(self.scan(), self.loop)

    async def scan(self):
        self.result_ready.emit("开始扫描中...")
        try:
            self.devices = await BleakScanner.discover()
            if self.devices:
                self.result_ready.emit("扫描完成，点击设备连接。")
                self.device_list_ready.emit(self.devices)
            else:
                self.result_ready.emit("未发现 BLE 设备")
        except Exception as e:
            self.result_ready.emit(f"扫描失败：{e}")

    def connect_device(self, address):
        asyncio.run_coroutine_threadsafe(self.connect_and_read(address), self.loop)

    async def connect_and_read(self, address):
        self.result_ready.emit(f"尝试连接设备 {address} ...")
        try:
            async with BleakClient(address) as client:
                if client.is_connected:
                    self.result_ready.emit("设备已连接，读取特征值中...")
                    try:
                        value = await client.read_gatt_char(CHARACTERISTIC_UUID)
                        value_str = value.hex()
                        self.result_ready.emit(f"读取成功：特征值 = {value_str}")
                    except Exception as e:
                        self.result_ready.emit(f"读取失败：{e}")
                else:
                    self.result_ready.emit("连接失败")
        except Exception as e:
            self.result_ready.emit(f"连接出错：{e}")